//===============================================
// Animation Shader
// Normal tri
//===============================================

#include "ShaderHelp.fxh"

cbuffer cbPerFrame
{
	float3 gEyePosW;
	Matrix gBoneMatrix[40];
};

cbuffer cbPerObject
{
	matrix gWorld : World;
	matrix gWVP : WorldViewProjection;
	matrix gViewInv : ViewInverse;
	matrix gViewProj;
};

Texture2D diffuseTexture : Diffuse;

float3 gPosLight : LIGHTPOS = {-70, 800, 200};
float4 gLightColor : LIGHTCOL = {0.9f, 0.9f, 0.9f, 1.0f};
float4 gLightSpec : LIGHTSPEC = {1.0f, 1.0f, 1.0f, 1.0f};
float4 gLightAmbient : LIGHTAMBIENT = {0.3f, 0.3f, 0.3f, 1.0f};

SamplerState diffuseSampler
{
	Filter = MIN_MAG_MIP_LINEAR;
	AddressU = WRAP;
	AddressV = WRAP;
};

struct VS_INPUT
{
    float3 Pos          : POSITION;         //position
    float3 Norm		: NORMAL;
    float2 Tex          : TEXCOORD;        //texture coordinate
    float3 Tan : TANGENT;
    float4 boneId : BONEID;
    float4 boneWeight : BONEWEIGHT;
};

struct PS_INPUT
{
    float4 Pos     : SV_POSITION;
    float3 Norm     : TEXCOORD0;
    float4 WorldPos  : TEXCOORD1;
    float2 Tex     : TEXCOORD2;
};


//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT VS( VS_INPUT vIn )
{
    PS_INPUT vOut = (PS_INPUT)0;
	
	float4 hPos = float4(vIn.Pos, 1);
	float4 result = 0;
	for(int i = 0; i < 4; ++i)
	{
		int index = vIn.boneId[i];
		if(index != -1)
		{
			result += vIn.boneWeight[i] * mul(hPos, gBoneMatrix[index]);
		}
	}
	//vOut.Pos = mul(result, gViewProj);
	vOut.Pos = mul(hPos, gWVP);
	vOut.WorldPos = mul(result, gWorld);
	vOut.Norm  = mul(vIn.Norm, (float3x3)gWorld);
	vOut.Norm = -normalize(vOut.Norm);
	vOut.Tex = vIn.Tex;
	
	return vOut;
}
	
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------

float4 PS( PS_INPUT input) : SV_Target
{
	float4 diffuse = diffuseTexture.Sample( diffuseSampler, input.Tex );
	
	// Kill transparant pixels
	clip( diffuse.a - 0.15f );
	
	float4 spec = float4(1,1,1,1);
	
	SurfaceInfo v = {input.WorldPos.xyz, input.Norm, diffuse, spec};
	
	Light L;
	L.pos = gPosLight;
	L.dir = normalize(gPosLight);
	L.ambient = gLightAmbient;
	L.diffuse = gLightColor;
	L.spec = gLightSpec;
	
	float3 litColor = ParallelLight(v, L, gViewInv[3]);
	
	return float4(litColor, 1.0f);
}


//--------------------------------------------------------------------------------------
// Technique
//--------------------------------------------------------------------------------------

RasterizerState DisableCulling
{
    CullMode = NONE;
};

RasterizerState EnableCulling
{
    CullMode = Back;
    //FillMode = Wireframe;
    FrontCounterClockwise = false;
};

BlendState DisableBlend
{
	BlendEnable[0] = FALSE;
};

DepthStencilState NoDepthStencil
{
	DepthEnable = true;
	StencilEnable = false;
};

technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
        
        SetRasterizerState(EnableCulling);       
		SetDepthStencilState(NoDepthStencil, 0);
		SetBlendState(DisableBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF);
    }
}

